<script setup lang='ts'>
import type { ElTree } from 'element-plus'
import type { VxeGridProps } from 'vxe-table'

import { useGetCBProductCategoryTreeByProductId, useGetCbSupplierQuoteDetail, useSaveSupplierQuote, useSubmitSupplierQuote } from '@fl/api/supplier'
import { SearchTable } from '@fl/components'
import { genOssUrl, oss } from '@fl/logics/oss'
import dayjs from 'dayjs'
import { cloneDeep, isNull } from 'lodash-es'
import NP from 'number-precision'

import { componentEum, data } from './constant'
import dialogCom from './dialog.vue'

const treeRef = ref<InstanceType<typeof ElTree>>()

const visible = ref(false)

const btnSize = 'small'

const tabRef1 = ref()

const tabRef2 = ref()

const route = useRoute()

const { back } = useRouter()

const productId = route.params?.productId

const projectId = route.params?.projectId

const categoryId = ref('')

const { data: CategoryTreeData, isLoading: CategoryTreeLoading } = useGetCBProductCategoryTreeByProductId(ref({ productId }))

const params = computed(() => {
    return {
        categoryId: categoryId.value,
        productId,
        projectId,
    }
})

const { data: QuoteDetailData, isLoading: QuoteDetailLoading } = useGetCbSupplierQuoteDetail(params)

const loading = computed(() => CategoryTreeLoading.value || QuoteDetailLoading.value)

const { isPending: savePending, mutate: saveMutate } = useSaveSupplierQuote()

const { isPending: submitPending, mutate: submitMutate } = useSubmitSupplierQuote()

const isAfterEnding = computed(() => dayjs().isAfter(QuoteDetailData.value?.endTime || ''))

provide('isAfterEnding', isAfterEnding)

const componentRef = ref()

const defaultProps = {
    children: 'children',
    label: 'categoryName',
}

const treeData = ref<any[]>([])

const gridOptions1 = computed<VxeGridProps>(() => {
    return {
        border: 'none',
        columnConfig: {
            resizable: false,
        },
        columns: [
            { field: 'usage', formatter: ({ row }) => {
                return `${row.usage}${QuoteDetailData.value?.unit || ''}`
            }, title: '净用量' },
            { slots: { default: 'lossRate' }, title: '综合损耗率' },
            { field: 'actualUsage', slots: { default: 'actualUsage' }, title: '实际用量' },
            { slots: { default: 'operate' }, title: '操作' },
        ],
        minHeight: 0,
    }
})

const gridOptions1Data = ref<any[]>([])

const gridOptions2 = computed<VxeGridProps>(() => {
    return {
        columns: [
            {
                field: 'itemName',
                title: '材料名称',
            },
            { field: 'model', title: '规格型号' },
            { field: 'unit', title: '报价单位' },
            { field: 'quote', slots: { default: 'quote' }, title: '报价金额' },
        ],
        minHeight: 0,
        rowConfig: {
            keyField: 'itemId',
        },
    }
})

const gridOptions2Data = ref<any[]>([])

const totalQuote = computed(() => {
    if (gridOptions2Data.value.length) {
        const sum = gridOptions2Data.value.reduce((accumulator: any, current: any) => {
            return Number(accumulator ?? 0) + Number((current.quote ?? 0))
        }, 0)
        return NP.round(sum * (gridOptions1Data.value[0].actualUsage ?? 0), 4)
    }
    return 0
})

const asideWidth = ref<number>(300)

let isResizing = false
let startX = 0
let startWidth = 0

function startResizing(event: MouseEvent) {
    isResizing = true
    startX = event.clientX
    startWidth = asideWidth.value

    document.addEventListener('mousemove', resizeAside)
    document.addEventListener('mouseup', stopResizing)
}

function resizeAside(event: MouseEvent) {
    if (isResizing) {
        const newWidth = startWidth + (event.clientX - startX)
        asideWidth.value = newWidth < 300 ? 300 : newWidth > 500 ? 500 : newWidth // 设置最小宽度为 50px
    }
}

function stopResizing() {
    isResizing = false
    document.removeEventListener('mousemove', resizeAside)
    document.removeEventListener('mouseup', stopResizing)
}

function showGroupPricePreview() {
    showDialog('GroupPricePreview')
}

function showPreparationDescription() {
    showDialog('PreparationDescription')
}

function showCalculationRules() {
    showDialog('CalculationRules')
}

function showCalculationFormula() {
    showDialog('CalculationFormula')
}

function showDialog(val: string) {
    componentRef.value = componentEum[val]
    visible.value = true
}

const saveParams = computed(() => {
    return {
        actualUsage: Number(gridOptions1Data.value?.[0]?.actualUsage),
        biddingProjectId: projectId,
        categoryId: categoryId.value,
        id: QuoteDetailData.value?.id || '',
        items: gridOptions2Data.value.map((item: any) => {
            return {
                ...item,
                quote: item.quote,
            }
        }),
        lossRate: gridOptions1Data.value?.[0]?.lossRate,
        productId,
        totalQuote: totalQuote.value,
    }
})

function save() {
    saveMutate(saveParams.value, {
        onSuccess: () => {
            ElMessage.success('操作成功')
        },
    })
}

function submit() {
    saveMutate(saveParams.value, {
        onSuccess: () => {
            submitMutate({ productId: String(productId), projectId: String(projectId) }, {
                onSuccess: () => {
                    ElMessage.success('操作成功')
                    back()
                },
            })
        },
    })
}
function formatActualUsage(row: any) {
    const result = NP.round(Number(row.usage) * (1 + ((row.lossRate ?? 0) / 100)), 4)
    row.actualUsage = result
    return result
}

function handleNodeClick(data: any, node: any) {
    if (data.children && data.children.length > 0) {
        if (treeRef.value) {
            treeRef.value.setCurrentKey(categoryId.value, false)
            node.expanded = !node.expanded
        }
    }
    else {
        saveMutate(saveParams.value, {
            onSuccess: () => {
                categoryId.value = data.id
            },
        })
    }
}

function filterFirstChildCbCategoryId(arr: any[]) {
    for (const item of arr) {
        if (item.children && item.children.length > 0) {
            const result = filterFirstChildCbCategoryId(item.children)
            return result ?? ''
        }
        else if (item.id) {
            return item.id ?? ''
        }
    }
    return ''
}

onMounted(() => {
    document.addEventListener('mouseup', stopResizing)
})

onUnmounted(() => {
    document.removeEventListener('mouseup', stopResizing)
})

watchEffect(() => {
    if (QuoteDetailData.value) {
        gridOptions1Data.value = []
        gridOptions2Data.value = []
        const params = {
            actualUsage: QuoteDetailData.value?.actualUsage,
            lossRate: QuoteDetailData.value?.lossRate ?? null,
            usage: QuoteDetailData.value?.usage,
        }
        gridOptions1Data.value.push(params)
        const result = QuoteDetailData.value?.supplierItemVOS.map((item: any) => {
            return {
                ...item,
                quote: item.quote ? Number(item.quote) : item.quote,
            }
        }) || []
        gridOptions2Data.value = cloneDeep(result)
    }
})

watchEffect(() => {
    if (CategoryTreeData.value) {
        treeData.value = cloneDeep(CategoryTreeData.value)
        const id = filterFirstChildCbCategoryId(treeData.value)
        setTimeout(() => {
            treeRef.value?.setCurrentKey(id, false)
            categoryId.value = id
        }, 100)
    }
})
</script>

<template>
    <el-skeleton v-if="CategoryTreeLoading"
                 :rows="3"
    />

    <template v-else>
        <el-container v-if="treeData.length"
                      class="h-800"
        >
            <el-aside class="p-10 mr-10 bg-#fff relative"
                      :style="{ width: `${asideWidth}px` }"
            >
                <div class="flex flex-col h-full">
                    <el-tree ref="treeRef"
                             :height="720"
                             :data="treeData"
                             :props="defaultProps"
                             highlight-current
                             node-key="id"
                             default-expand-all
                             :expand-on-click-node="false"
                             @node-click="handleNodeClick"
                    />
                </div>

                <div v-if="false"
                     class="resizer"
                     @mousedown="startResizing"
                />
            </el-aside>

            <el-main class="bg-#fff">
                <el-skeleton v-if="!(categoryId && !loading)"
                             :rows="3"
                />

                <el-card v-else
                         :key="categoryId"
                         shadow="never"
                         h-full
                         class="flex! flex-col!"
                         :body-style="{ flex: '1', overflow: 'auto' }"
                >
                    <template #header>
                        <div flex
                             justify-between
                             items-center
                        >
                            <div class="title">
                                投标清单
                            </div>

                            <div>
                                <el-button type="primary"
                                           :size="btnSize"
                                           @click="showGroupPricePreview"
                                >
                                    组价预览
                                </el-button>

                                <el-button type="primary"
                                           :size="btnSize"
                                           color="#fff0f0"
                                           class="text-#da0004!"
                                           @click="showPreparationDescription"
                                >
                                    编制说明
                                </el-button>

                                <el-button type="primary"
                                           :size="btnSize"
                                           color="#fff0f0"
                                           class="text-#da0004!"
                                           @click="showCalculationRules"
                                >
                                    计算规则
                                </el-button>
                            </div>
                        </div>
                    </template>

                    <div px-20
                         py-10
                         h-full
                    >
                        <div class="title my-20">
                            工程量
                        </div>

                        <SearchTable v-bind="gridOptions1"
                                     ref="tabRef1"
                                     :key="gridOptions1Data.length"
                                     :data="gridOptions1Data"
                                     header-cell-class-name="backfff"
                        >
                            <template #lossRate="{ row }">
                                <div v-if="isAfterEnding">
                                    {{ `${row.lossRate || 0} %` }}
                                </div>

                                <div v-else
                                     flex
                                     gap-10
                                     items-center
                                >
                                    <el-input-number v-model="row.lossRate"
                                                     :min="0"
                                                     :max="100"
                                                     :precision="0"
                                                     style="width: 100%"
                                    />
                                    %
                                </div>
                            </template>

                            <template #actualUsage="{ row }">
                                {{ formatActualUsage(row) }}{{ QuoteDetailData.unit }}
                            </template>

                            <template #operate>
                                <ElButton v-if="QuoteDetailData?.ruleType !== 1"
                                          text
                                          type="primary"
                                          @click="showCalculationFormula"
                                >
                                    查看计算公式
                                </ElButton>
                            </template>
                        </SearchTable>

                        <div class="title my-20">
                            报价清单
                        </div>

                        <SearchTable v-bind="gridOptions2"
                                     ref="tabRef2"
                                     :key="gridOptions2Data.length"
                                     :data="gridOptions2Data"
                        >
                            <template #quote="{ row }">
                                <div v-if="isAfterEnding">
                                    {{ row.quote || '暂未报价' }}
                                </div>

                                <div v-else
                                     flex
                                     gap-10
                                     items-center
                                >
                                    <el-input-number v-model="row.quote"
                                                     :min="0"
                                                     :max="1000000000"
                                                     style="width: 100%"
                                                     @blur="() => {
                                                         row.quote = isNull(row.quote) ? row.quote : NP.round(row.quote, 4)
                                                     }"
                                    />
                                </div>
                            </template>
                        </SearchTable>

                        <div class="title my-20">
                            报价说明
                        </div>

                        <el-tabs v-if="gridOptions2Data.length"
                                 type="border-card"
                        >
                            <el-tab-pane v-for="item in gridOptions2Data"
                                         :key="item.id"
                                         :label="item.itemName"
                            >
                                {{ item?.priceDetail }}
                            </el-tab-pane>
                        </el-tabs>

                        <div class="p-10 my-20 bg-#f7f8fa text-#da0004 font-bold">
                            报价合计：{{ totalQuote }}元
                        </div>
                    </div>

                    <template #footer>
                        <div flex
                             justify-center
                             items-center
                        >
                            <el-button @click="back">
                                {{ isAfterEnding ? '返回' : '取消' }}
                            </el-button>

                            <template v-if="!isAfterEnding">
                                <el-button type="primary"
                                           color="#fff0f0"
                                           class="text-#da0004!"
                                           :loading="savePending"
                                           @click="save"
                                >
                                    保存
                                </el-button>

                                <el-button type="primary"
                                           :loading="submitPending"
                                           @click="submit"
                                >
                                    完成组价
                                </el-button>
                            </template>
                        </div>
                    </template>
                </el-card>
            </el-main>
        </el-container>

        <el-empty v-else
                  h-full
                  :image="genOssUrl(oss.go.nodata)"
        >
            <el-button type="primary"
                       @click="back"
            >
                返回
            </el-button>
        </el-empty>
    </template>

    <dialogCom v-model:id="productId"
               v-model:projectId="projectId"
               v-model:categoryId="categoryId"
               v-model:visible="visible"
               v-model:componentRef="componentRef"
    />
</template>

<style lang="scss" scoped>
.el-main {
    padding: 20px;
}

.el-aside {
    overflow: hidden;
}

.resizer {
    position: absolute;
    top: 0;
    right: 0;
    width: 3px;
    height: 100%;
    cursor: ew-resize;
    background-color: rgb(0 0 0 / 20%);
}

.title {
    font-size: 16px;
    font-weight: bold;
}

:deep(.el-card),
:deep(.el-card__footer) {
    border: none;
}
</style>

<style>
.backfff {
    background: #fff !important;
}
</style>
